package com.newenergy.light.ble;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.newenergy.light.Helper.BleDataHelper;
import com.newenergy.light.Helper.CmdType;
import com.newenergy.light.Helper.EncryUtil;
import com.newenergy.light.Helper.SPUtil;
import com.newenergy.light.callback.BleAdvertiseCallback;
import com.newenergy.light.callback.BleScanCallBack;
import com.newenergy.light.callback.NotifyCallBack;
import com.newenergy.lightlibrary.R;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * Created by jnl on 2017/6/15.
 *
 **/

public class AdvertiserManager {

    private Context mContext;
    private float mDensity;
    public String toastMessage = "";


    public int scanType = 0;//0代表用默认的解密，1代表用当前家庭码解密

    public String familyId = "12345678";

    public int mSeed = 73;
    public int mFeedBack = 4777;

    private int NORMAL_ID = HeaderHelper.convertHeaders((byte) 0x4E, (byte) 0x6F);

    private int MATCH_ID = HeaderHelper.convertHeaders((byte) 0x69, (byte) 0x63);

    public boolean isAdvertising = false;
    public boolean isScaning = false;
    public final int HANDLE_NOTIFY_STATUS = 0x02;
    public final int HANDLE_STOP_SCAN = 0x03;

    private final int HANDLE_STOP_ADVERTISE = 0x05;

    private BluetoothAdapter mBleAdapter;

    public CmdType currCmd = CmdType.NONE;
    public int currGroupId = -1;
    public String mLightId = "1";
    public boolean mIsFail;
    private NotifyCallBack mNotifyCallBack;
    private Toast  mToast;
    private TextView mTvMsg;
    private BleScanCallBack mBleScanCallBack;
    private int delayNotifyTime = 1000;

    private ScanSettings mScanSettings;
    private List<ScanFilter> mScanFilters;
    private BluetoothLeScanner mLeScanner;
    private String mLdHex = "00";
    private String ZF = "06";
    private int mAdvertiseNumber=50;
    //标记是否是发送分享遥控器
    public boolean isRemoteShare=false;
    public boolean isBleAdvertise = false;

    /**
     * 获取单例
     *
     * @return
     */
    public static AdvertiserManager getInstance() {
        return Wrapper.instance;
    }


    public void setContext(Context context){
        if (context==null) return;
        if (mContext == null) {
            mContext = context;
            mDensity = context.getResources().getDisplayMetrics().density;
            SPUtil.init(context);
        }
    }


    private AdvertiserManager() {
//        BleDataHelper.init(context);
        mBleAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!mBleAdapter.isEnabled()) {
            mBleAdapter.enable();
        }
        initScan();
    }


    public void sendNotifyMessage(String msg, int delay) {
        toastMessage = msg;
        sendEmptyMessage(HANDLE_NOTIFY_STATUS, delay);
    }


    public void controlFan(String id1, String cmd) {
        String serial = BleDataHelper.getFanSerial();
        StringBuilder builder = new StringBuilder();
        builder.append("7264").append(serial).append("00").append(id1).append(cmd)
                .append("000000000000000000");
        String cmdData = builder.toString();
        byte[] datas = BleDataHelper.StrToBytes(cmdData);
        stopAdvertise();
        sendEmptyMessage(HANDLE_STOP_ADVERTISE,mAdvertiseNumber*120);
        BleAdvHelper.getInstance().send(NORMAL_ID, datas,
                null);
    }


    private static class Wrapper {
        @SuppressLint("StaticFieldLeak")
        private static AdvertiserManager instance = new AdvertiserManager();

    }

    private Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case HANDLE_NOTIFY_STATUS:
//                    String message = (String) msg.obj;
                    toast(toastMessage);
                    break;
                case HANDLE_STOP_SCAN:
                    stopScan();
                    break;
                case HANDLE_STOP_ADVERTISE:

                    stopAdvertise();
                    break;
            }
        }
    };

    public void showToast(String msg){
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }



    public void toast(String msg) {
        notifyBtnEnabel();
        Context context = mContext;
        // 找到toast布局的位置
        View layout = View.inflate(context, R.layout.toast, null);
        TextView tvMsg = (TextView) layout.findViewById(R.id.tv_msg);
        tvMsg.setSelected(mIsFail);
        tvMsg.setText(msg);

        if (mToast == null) mToast = new Toast(context);
        // 设置toast文本，把设置好的布局传进来
        mToast.setView(layout);
        // 设置土司显示在屏幕的位置
        mToast.setGravity(Gravity.FILL_HORIZONTAL | Gravity.TOP, 0,
                dpToPx(10));
        mToast.setDuration(Toast.LENGTH_SHORT);
        // 显示土司
        mToast.show();

    }

    private void notifyBtnEnabel() {
        if (mNotifyCallBack != null) {
            mNotifyCallBack.notifyBtnEnabel();
        }
    }


//    /**
//     * 长度 距离
//     *
//     * @param distance
//     * @return
//     */
    public int dpToPx(int distance) {
        return (int) (distance * mDensity + 0.5);
    }

    /**
     * 取消所有消息(取消广播)
     */
    public void cancelAdvertise() {
        stopAdvertise();
    }

    /**
     * 开启新广播消息
     * @param sendData 发送的加密数据
     * @param advertiseNumber 发送的包数
     * @param advertiseType  发送的类型，1代表的是控制，2代表的是强制恢复默认专用
     * @param deviceType     发送的设备类型 7101代表的是球泡灯,
     */
    public void startAdvertise(String sendData, int advertiseNumber,int advertiseType,String deviceType) {
        // 取消吐司
        if (mToast != null) mToast.cancel();
//        if (mBleAdapter == null || mBleAdapter.getBluetoothLeAdvertiser() == null) {
////            openBlueTooth();
//            return;
//        }
        stopAdvertise();
        sendEmptyMessage(HANDLE_STOP_ADVERTISE, advertiseNumber * 120);
        sendAdvertise(sendData,advertiseType,deviceType);
    }

    /**
     * 发送延时消息
     *
     * @param tag
     * @param delayTime
     */
    public void sendEmptyMessage(int tag, long delayTime) {
        if (mHandler.hasMessages(tag)) {
            mHandler.removeMessages(tag);
        }
        mHandler.sendEmptyMessageDelayed(tag, delayTime);
    }

    /**
     * 移除handle 消息
     *
     * @param tag
     */
    private void removeHandleMessages(int tag) {
        if (mHandler.hasMessages(tag)) {
            mHandler.removeMessages(tag);
        }
    }


    /**
     * 发送广播数据
     * @param cmdData
     * @param advertiseType 1代表的是控制，2代表的是强制恢复默认专用
     * @param deviceType 发送的设备类型
     */
    public void sendAdvertise(String cmdData,int advertiseType,String deviceType) {
        int manufacturerID = NORMAL_ID;
        if (advertiseType == 2) {
            manufacturerID = MATCH_ID;
        }

        int length = cmdData.length();
        if (length !=26){
          toast("数据长度有误="+length);
            return;
        }
        if (isRemoteShare){
            ZF = "00";
        }
        byte[] data = BleDataHelper.getSendData(cmdData,advertiseType,deviceType,  ZF);
        isAdvertising = true;
//        if (!isBleAdvertise) {
//            Log.i("LFX", "sendAdvertise: 远程控制,本地不控制");
//            return;
//        }
        if (mBleAdapter != null && mBleAdapter.getBluetoothLeAdvertiser() != null) {
//            openBlueTooth();
            BleAdvHelper.getInstance().send(manufacturerID, data,mAdvertiseCallback);
        }

//        BleAdvHelper.getInstance().send(manufacturerID, data,mAdvertiseCallback);
        ZF = "06";

    }



    /**
     * 停止广播
     */
    public void stopAdvertise() {
        BleAdvHelper.getInstance().stop(mAdvertiseCallback);
        isAdvertising = false;
    }

    private void initScan() {
        getBleScanner();
        mScanSettings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .build();
        mScanFilters = new ArrayList<>();
        mScanFilters.add(new ScanFilter.Builder()
                .build());
    }

    /**
     * 开启扫描
     */
    public void startScan() {

        removeHandleMessages(HANDLE_STOP_SCAN);
        openBlueTooth();

        getBleScanner();
        if (mLeScanner == null) return;
        mLeScanner.startScan(mScanFilters, mScanSettings,
                mScanCallback);
    }

    private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            byte[] bytes = result.getScanRecord().getBytes();
            handleScanData(bytes);
        }

    };


    public void handleScanData(byte[] bytes) {
//             * subHexStr(content,5,4) 获取新系统码
//                * subHexStr(content,9,2) 获取序号
//                * subHexStr(content,12,13)  获取需要解密数据
//        Log.e("LFX", bytes.toString());
//        if (bytes.length != 25) return;
        String scanData = BleDataHelper.bytesToString(bytes, 26);
//        Log.e("LFX", scanData);
        String sytemId = BleDataHelper.subHexStr(scanData, 5, 4);//系统id
        String sytemDeviceType = BleDataHelper.subHexStr(scanData, 8, 1);//系统中设备类型sytemDeviceType例如风扇灯03

        if (!sytemId.startsWith("4E6F72")) {
            return;
        }
        String serial = BleDataHelper.subHexStr(scanData, 9, 2);//发送序号
        int seed = 73;
        int feedBack = 4777;

        if (scanType != 0) {
            seed = mSeed;
            feedBack = mFeedBack;
        }

        //获取需要解密的数据
        String toDecryptData = BleDataHelper.subHexStr(scanData, 12, 13);

        //解密后的数据
        String cmdData = EncryUtil.decrypt(toDecryptData, seed, feedBack, serial);

        String cmdType = BleDataHelper.subHexStr(cmdData, 0, 1);//命令类型
        String familyID = BleDataHelper.subHexStr(cmdData, 1, 4);//家庭码
        String deviceId = BleDataHelper.subHexStr(cmdData, 1, 6);//设备ID-UUID
        String st = BleDataHelper.subHexStr(cmdData, 12, 1);//st
        String groupId = BleDataHelper.subHexStr(cmdData, 5, 1);//组号

        String deviceType = BleDataHelper.subHexStr(cmdData, 1, 1);//系统中设备类型sytemDeviceType例如风扇灯03


//        String count = BleDataHelper.subHexStr(cmdData, 11, 1);//测试回传包数
        Log.e("LFX", "sytemDeviceType==="+sytemDeviceType+"=====deviceType==="+deviceType);
        if (cmdType.equals("F5") &&sytemDeviceType.equals(deviceType)) {
            if (mBleScanCallBack != null) {
                mBleScanCallBack.foundDevice(deviceId);
                Log.e("LFX", "scanData==="+scanData);
            }

        } else if (cmdType.equals("F6") && familyID.equalsIgnoreCase(familyId)) {
            if (st.equals("01")){//添加成功
                if (mBleScanCallBack != null) {
                    mBleScanCallBack.saveDevice(groupId);
                }

            }

        }

        if (cmdType.equals("F6") && st.equals("01")) {
            Log.e("LFX", "familyID===" + familyID + "=====" + "familyId====" + familyId);
        }


        Log.i("scanResult", "sytemId==" + sytemId + "    familyID==" +
                familyID + "  cmdType==" + cmdType + "   deviceId==" +
                deviceId + " st==" + st);
    }

    /**
     * 停止扫描
     */
    public void stopScan() {
        removeHandleMessages(HANDLE_STOP_SCAN);
        openBlueTooth();
        getBleScanner();
        if (mLeScanner == null) return;
        mLeScanner.stopScan(mScanCallback);
    }

    private void getBleScanner() {
        if (mBleAdapter != null && mLeScanner == null)
            mLeScanner = mBleAdapter.getBluetoothLeScanner();
    }

    /**
     * 请求打开蓝牙
     */
    private void openBlueTooth() {
        if (mBleAdapter != null) {
            if (!mBleAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                enableBtIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mContext.startActivity(enableBtIntent);
            }
        } else {
            Log.i("blueTooth", "该手机不支持蓝牙");
        }
    }


     private AdvertiseCallback mAdvertiseCallback = new BleAdvertiseCallback();


    /**
     * 接收广播数据，并处理
     * 校验数据
     *
     * @param bytes
     */
/*    private void handleScanData(byte[] bytes) {
        if (mBleScanCallBack == null) return;
        String[] results = BleDataHelper.checkScanData(bytes);
        if (results == null || results.length != 3) return;
        String id1 = results[0];
        mBleScanCallBack.foundDevice(id1);
        if (!mLightId.equals(id1)) return;
        switch (results[2]) {
            case "03"://对码成功指令的ACK
                mBleScanCallBack.saveDevice(id1);
                stopAdvertise();
                mIsFail = false;
                sendNotifyMessage("添加灯成功。",delayNotifyTime);
                mLightId = "1";
                break;


            case "01"://删除指令的ACK
                mBleScanCallBack.deleteDevice(id1);
                stopAdvertise();
                mIsFail = false;
                sendNotifyMessage("删除灯成功。", delayNotifyTime);
                mLightId = "1";
                break;


            case "02"://组控的ACK
//                updateGroup(id1);
                mLightId = "1";
                break;
        }
    }*/




    /**
     * 更新组操作
     *
     * @param id1
     */
   /* private void updateGroup(String id1) {
        int groupId = currGroupId;
        if (groupId >= 1 && currCmd == CmdType
                .ADD_LIGHT_TO_GROUP) {
            mBleScanCallBack.addLightToGroup(id1, groupId);
            mIsFail = false;
            sendNotifyMessage("添加灯到组成功。", delayNotifyTime);
            currGroupId = -1;
        } else if (currCmd ==CmdType.REMOVE_LIGHT_FROM_GROUP) {
            mBleScanCallBack.removeLightFromGroup(id1);
            mIsFail = false;
            sendNotifyMessage("从组移除灯成功。",delayNotifyTime);
        }
        stopAdvertise();
    }*/


    /**
     * 扫描结果会掉接口
     */
    public void setBleScanCallBack(BleScanCallBack bleScanCallBack) {
        mBleScanCallBack = bleScanCallBack;
    }
}
